<template>
  <div class="particles-container" ref="particleContainerRef" @mousemove="handleMouseMove" @mouseleave="resetMouseEffect"></div>
</template>

<script>
export default {
  name: 'ParticlesBackground',
  data() {
    return {
      particles: [],
      ctx: null,
      canvas: null,
      animationFrameId: null,
      ParticleClass: null,
      mouse: {
        x: null,
        y: null,
        radius: 100 // 鼠标影响半径
      }
    };
  },
  mounted() {
    this.initParticles();
    window.addEventListener('resize', this.handleResize);
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.handleResize);
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId);
    }
    const container = this.$refs.particleContainerRef;
    if (container && this.canvas) {
      if (container.contains(this.canvas)) {
        container.removeChild(this.canvas);
      }
    }
  },
  methods: {
    handleMouseMove(event) {
      if (!this.canvas) return;
      const rect = this.canvas.getBoundingClientRect();
      this.mouse.x = event.clientX - rect.left;
      this.mouse.y = event.clientY - rect.top;
    },
    resetMouseEffect() {
      this.mouse.x = null;
      this.mouse.y = null;
    },
    initParticles() {
      const container = this.$refs.particleContainerRef;
      if (!container) return;

      if (this.canvas && container.contains(this.canvas)) {
        container.removeChild(this.canvas);
      }
      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId);
      }


      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      this.particles = [];
      this.ctx = ctx;
      this.canvas = canvas;

      canvas.width = container.clientWidth;
      canvas.height = container.clientHeight;
      container.appendChild(canvas);

      const self = this; // For Particle class closure

      class Particle {
        constructor(canvasWidth, canvasHeight) {
          this.x = Math.random() * canvasWidth;
          this.y = Math.random() * canvasHeight;
          this.originX = this.x; // Store original position for effects
          this.originY = this.y;
          this.size = Math.random() * 2.8 + 0.8; // 粒子大小略微增加
          this.speedX = (Math.random() * 0.5 - 0.25) * 0.7; // 粒子移动速度减慢，更柔和
          this.speedY = (Math.random() * 0.5 - 0.25) * 0.7;
          this.colorHue = Math.random() * 360; // 色相，用于HSL颜色
          this.opacity = Math.random() * 0.4 + 0.3; // 基础透明度
          this.maxLife = Math.random() * 100 + 50; // Particle lifespan for shimmer effect
          this.life = this.maxLife;
        }

        update(canvasWidth, canvasHeight, mouse) {
          // Mouse interaction: particles move away from cursor
          if (mouse.x != null && mouse.y != null) {
            const dxMouse = this.x - mouse.x;
            const dyMouse = this.y - mouse.y;
            const distanceMouse = Math.sqrt(dxMouse * dxMouse + dyMouse * dyMouse);
            const forceDirectionX = dxMouse / distanceMouse;
            const forceDirectionY = dyMouse / distanceMouse;
            const maxDistance = mouse.radius;
            const force = (maxDistance - distanceMouse) / maxDistance; //
            const directionX = forceDirectionX * force * 0.8; // 强度系数减小，效果更细腻
            const directionY = forceDirectionY * force * 0.8;

            if (distanceMouse < maxDistance) {
              this.x += directionX;
              this.y += directionY;
            }
          }


          this.x += this.speedX;
          this.y += this.speedY;

          if (this.x < 0 || this.x > canvasWidth) this.speedX *= -1;
          if (this.y < 0 || this.y > canvasHeight) this.speedY *= -1;

          // Shimmer / life effect
          this.life--;
          if (this.life <= 0) {
            this.life = this.maxLife;
            this.colorHue = Math.random() * 360; // Reset color on "rebirth" for dynamism
          }
        }

        draw(ctx) {
          const shimmerOpacity = this.opacity * (Math.sin(this.life * 0.1) * 0.3 + 0.7); // Pulsating opacity
          ctx.fillStyle = `hsla(${this.colorHue}, 70%, 70%, ${shimmerOpacity})`; // 使用HSL创造柔和多彩的粒子
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
          ctx.fill();

          // Add a subtle glowing core for some particles (optional performance hit)
          if (this.size > 2) {
            const gradient = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.size * 0.5);
            gradient.addColorStop(0, `hsla(${this.colorHue}, 90%, 85%, ${shimmerOpacity * 0.5})`);
            gradient.addColorStop(1, `hsla(${this.colorHue}, 70%, 70%, 0)`);
            ctx.fillStyle = gradient;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size * 0.7, 0, Math.PI * 2); // Smaller glow core
            ctx.fill();
          }
        }
      }

      this.ParticleClass = Particle;
      this.createParticles();
      if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId); // Ensure no duplicates
      this.animate();
    },

    createParticles() {
      if (!this.canvas || !this.ParticleClass) return;
      const numParticles = Math.floor((this.canvas.width * this.canvas.height) / 10000); // 增加粒子密度
      const minParticles = 70;
      const maxParticles = 120; // 最大粒子数增加
      const particleCount = Math.max(minParticles, Math.min(numParticles, maxParticles));

      this.particles = [];
      for (let i = 0; i < particleCount; i++) {
        this.particles.push(new this.ParticleClass(this.canvas.width, this.canvas.height));
      }
    },

    animate() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

      for (let i = 0; i < this.particles.length; i++) {
        this.particles[i].update(this.canvas.width, this.canvas.height, this.mouse);
        this.particles[i].draw(this.ctx);

        for (let j = i + 1; j < this.particles.length; j++) { // Start j from i + 1
          const dx = this.particles[i].x - this.particles[j].x;
          const dy = this.particles[i].y - this.particles[j].y;
          const distance = Math.sqrt(dx * dx + dy * dy);

          if (distance < 130) { // 连接距离
            const opacity = 0.25 * (1 - distance / 130); // 连接线透明度更平滑
            this.ctx.beginPath();
            this.ctx.strokeStyle = `hsla(${this.particles[i].colorHue}, 70%, 80%, ${opacity * 0.7})`; // 连接线颜色与粒子相关联
            this.ctx.lineWidth = 0.4; // 连接线宽度
            this.ctx.moveTo(this.particles[i].x, this.particles[i].y);
            this.ctx.lineTo(this.particles[j].x, this.particles[j].y);
            this.ctx.stroke();
          }
        }
      }
      this.animationFrameId = requestAnimationFrame(this.animate);
    },
    handleResize() {
      const container = this.$refs.particleContainerRef;
      if (!container || !this.canvas || !this.ctx) return;

      this.canvas.width = container.clientWidth;
      this.canvas.height = container.clientHeight;
      this.createParticles(); // Recreate particles with correct density
    }
  }
};
</script>

<style scoped>
.particles-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: linear-gradient(145deg, #1a1a2e 0%, #10163a 30%, #0f0c29 70%); /* 更丰富的背景渐变 */
  overflow: hidden;
  filter: brightness(1.1); /* 轻微提亮整体效果 */
}
canvas {
  display: block; /* Fix potential layout issues */
}
</style>
